﻿/*
 * Twipler - Twitter Web Client with features.
 *  
 *  Copyright (C) 2010. Ian Quigley
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details. 
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Twipler.Xtensions;

namespace Twipler.App.Session
{
	public class InnerSessionFactory
	{
		private static List<IInnerSession> Sessions;

		static InnerSessionFactory()
		{
			lock (typeof(InnerSessionFactory))
				Sessions = new List<IInnerSession>();
		}

		public static IInnerSession Request(string sessionId)
		{
			object[] dbg = Current.Log.EnterMethod("SessionTrack.Request [" + sessionId + "]");

			if (!AreSessionsAvailable())
			{
				Current.Log.ExitMethod(dbg, " no free sessions");
				return new InnerSessionEmpty();
			}

			Current.Log.ExitMethod(dbg, " create new session");
			InnerSession track = new InnerSession(sessionId);

			lock (typeof(InnerSession))
				Sessions.Add(track);

			return track;
		}

		public static void Delete(string sessionId)
		{
			IInnerSession delete;
			lock (typeof(InnerSession))
			{
				delete = Sessions.FirstOrDefault(s => s.SessionId == sessionId);
				if (delete == null)
					return;

				Sessions.Remove(delete);
			}

			delete.CleanUp();
		}

		public static DateTime ServiceMaintenceAt()
		{
			return DateTime.MaxValue;
		}

		public static bool AreSessionsAvailable()
		{
			lock (typeof(InnerSessionFactory))
				return (GetSessionCount() < GetSessionCountLimit());
		}

		public static int? GetSessionCountLimit()
		{
			if (HttpContext.Current == null)
				return int.MaxValue;

			if (HttpContext.Current.Application["SessionCountLimit"] == null)
				HttpContext.Current.Application["SessionCountLimit"] = int.MaxValue;

			return (int)HttpContext.Current.Application["SessionCountLimit"];
		}

		public static int GetSessionCount()
		{
			lock (typeof(InnerSessionFactory))
				return Sessions.Count();
		}

		public static IEnumerable<IInnerSession> GetSessions()
		{
			lock (typeof(InnerSessionFactory))
				return from s in Sessions select s;
		}
	}
}
